`timescale 1 ns / 1 ps
/*------------------- include --------------------*/
`ifndef __SIM__
`define __INCLUDE__
`endif 


`ifdef __INCLUDE__ 
`include "../rtl/serving/serving.v"
`endif 
/*-----------------------------------------------*/

`ifndef SYS_FREQ
`define SYS_FREQ 27_000_000  // 系统时钟频率
`endif 
module top(
    input wire clk , 
    output reg led ,
    output reg txd ,
    
    output reg  spi0_cs ,
    output reg  spi0_sck ,
    output reg  spi0_mosi ,
    input  wire spi0_miso ,
    
    // i2c0 引脚
    output reg i2c0_scl ,
    inout  wire    i2c0_sda 
); 

/*---------------------------- mcu nets --------------------------*/

reg  rst_n ;
reg [12:0] rst_cnt = 0  ;

reg [31:0]tik ;
reg i2c0_sda_r =0 ;


// reg timer_src ;

// I2C sda 线适配 
`ifndef __SIM__
assign i2c0_sda = i2c0_sda_r?1'bz:1'b0 ;
`else 
assign i2c0_sda = i2c0_sda_r?1'b1:1'b0 ;
`endif 

// 产生复位信号
always @(posedge clk ) begin
    {rst_cnt , rst_n } <= { {&rst_cnt ? rst_cnt : rst_cnt + 1'b1}  ,  {&rst_cnt} } ;
end
/*----------------------------- 模块 ------------------------------*/
wire [31:0]wb_adr;
wire [31:0]wb_dat;
wire [3:0] wb_sel;
wire wb_we ;
wire wb_stb;
reg  [31:0]wb_rdt;
reg  wb_ack;

serving #(
    .memfile ("firmware.hex"),
    .memsize (16384) ,// bytes 
    .RESET_STRATEGY("MINI")
)mcu
(
    .i_clk(clk),
    .i_rst(~rst_n),
    // .i_timer_irq(timer_src),

    .o_wb_adr(wb_adr), // output wire [31:0] 
    .o_wb_dat(wb_dat), // output wire [31:0] 
    .o_wb_sel(wb_sel), // output wire [3:0]  
    .o_wb_we (wb_we ), // output wire 	      
    .o_wb_stb(wb_stb), // output wire 	      
    .i_wb_rdt(wb_rdt), // input wire [31:0]  
    .i_wb_ack(wb_ack)  // input wire 	      
);



always @(posedge clk) begin 
    wb_ack <= 1'b0;
    // 写数据
    if(wb_stb & wb_we & !wb_ack ) begin
        wb_ack <= 1'b1;
        // led 接口
        if(wb_adr == 32'h80000000)begin
            led <= wb_dat[0:0] ;
        end
        // spi 接口 
        if(wb_adr == 32'h80000200)begin
            spi0_sck  <= wb_dat[1] ;
            spi0_cs   <= wb_dat[2] ;
            spi0_mosi <= wb_dat[3] ;
        end

        // i2c 接口
        if(wb_adr == 32'h80000300)begin
            i2c0_scl <= wb_dat[0] ;
            i2c0_sda_r <= wb_dat[1] ;
        end

        // 软件串口 tx
        if(wb_adr == 32'h80000400)begin
            txd <= wb_dat[0] ;
        end
        
    end 

    //读数据
    if(wb_stb & !wb_we & !wb_ack ) begin
        wb_ack <= 1'b1;
        if(wb_adr == 32'h80000000) wb_rdt <= {31'd0,led} ;
        if(wb_adr == 32'h80000100) wb_rdt <= tik ;
        if(wb_adr == 32'h80000200) begin 
            wb_rdt[0] <= spi0_miso ;
            wb_rdt[1] <= spi0_sck  ;
            wb_rdt[2] <= spi0_cs   ;
            wb_rdt[3] <= spi0_mosi ;
        end 
        if(wb_adr == 32'h80000300) wb_rdt[1:0] <= {i2c0_sda , i2c0_scl} ;

        if(wb_adr == 32'h80000400) wb_rdt[0] <= txd;
    end
end 


reg [$clog2(`SYS_FREQ/1000)-1:0] clkcnt = 0 ; 
always @(posedge clk) begin 
    if(rst_n==1'b0) tik <= 'd0 ;
    else begin
        if(~|clkcnt)tik <= tik + 1'b1 ;
    end

    clkcnt <= (~|clkcnt) ? `SYS_FREQ/1000 : clkcnt - 1'b1 ;
end 




endmodule
